package plp.functional2.expression;

import java.util.Map;

import plp.expressions1.util.Tipo;
import plp.expressions2.expression.Expressao;
import plp.expressions2.expression.Valor;
import plp.expressions2.memory.AmbienteCompilacao;
import plp.expressions2.memory.AmbienteExecucao;
import plp.expressions2.memory.VariavelJaDeclaradaException;
import plp.expressions2.memory.VariavelNaoDeclaradaException;
import plp.functional1.expression.TuplaException;

public class ExpElementoMap implements Expressao {

	private Expressao expressao1;

	private Expressao expressao2;

	private ValorMap valorMap;
	private Valor mapKey;

	public ExpElementoMap(Expressao exp1, Expressao exp2) {
		expressao1 = exp1;
		expressao2 = exp2;
	}

	public Valor avaliar(AmbienteExecucao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException,
			TuplaException, MapException {
		
		try {

			valorMap = (ValorMap) expressao1.avaliar(amb);
			mapKey = (Valor)expressao2.avaliar(amb);
			
			for (Map.Entry<Expressao, Expressao> map : valorMap.valor().entrySet()) {
				if (mapKey.equals(map.getKey())) {
					return (Valor)map.getValue();
				}
			}

			throw new MapException("chave inexistente.");
		} catch (ClassCastException e) {
			throw new MapException("erro de tipo.");
		}
	}

	public boolean checaTipo(AmbienteCompilacao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
		return true;
	}

	public Tipo getTipo(AmbienteCompilacao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {

		return valorMap.getTipo(amb);
	}

}
